package org.light.framework.ioc;

import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.light.framework.Consts;

public class DefaultFactory implements IFactory {

	private static Map<String, Object> beanMap = new HashMap<String, Object>();

	static {

		DefaultFactory factory = new DefaultFactory();

		// 组件配置文件所在路径
		factory.init(Consts.CONFIG_COMPONENT);
	}

	/**
	 * * bean工厂的初始化,并进入属性注入
	 * 
	 * @param xml
	 *            配置文件
	 */
	private void init(String resourceName) {
		try {

			String resourcePath = Thread.currentThread().getContextClassLoader().getResource("").getPath()+ resourceName;
			File file = new File(resourcePath);

			if (!file.exists()) {
				System.out.println("文件不存在：" + file);
			}

			// 解析xml
			SAXReader reader = new SAXReader();
			Document doc = reader.read(file);
			Element root = doc.getRootElement();
			Element beanNode;
			// 遍历bean
			for (Iterator<?> i = root.elementIterator("bean"); i.hasNext();) {
				beanNode = (Element) i.next();

				// 获取bean的属性id和class
				Attribute id = beanNode.attribute("id");
				Attribute className = beanNode.attribute("class");

				// 利用Java反射机制，通过class的名称获取Class对象
				Class<?> beanClass = Class.forName(className.getText());

				// 实例化对象
				Object obj = beanClass.newInstance();

				// 设置对象属性值
				setBeanProperty(beanNode, beanClass, obj);

				// 将对象放入beanMap中，其中key为id值，value为对象
				beanMap.put(id.getText(), obj);
			}
		} catch (Exception e) {
			System.out.println(e.toString());
			e.printStackTrace();
		}
	}

	// 设置对象属性值
	private static void setBeanProperty(Element beanNode, Class<?> beanClass, Object obj) throws Exception {
		// 设置值的方法
		Method method = null;
		// 获取对应class的信息
		java.beans.BeanInfo beanInfo = java.beans.Introspector.getBeanInfo(beanClass);
		// 获取其属性描述
		java.beans.PropertyDescriptor proDescriptor[] = beanInfo.getPropertyDescriptors();
		// 遍历该bean的property属性
		for (Iterator<?> ite = beanNode.elementIterator("property"); ite.hasNext();) {
			Element beanPro = (Element) ite.next();
			// 获取该property的name属性
			Attribute name = beanPro.attribute("name");
			Attribute ref = beanPro.attribute("ref");
			Object proVal = null;
			if (ref != null) {
				proVal = beanMap.get(ref.getValue());
			} else {
				// 获取该property的子元素value的值
				for (Iterator<?> ite1 = beanPro.elementIterator("value"); ite1.hasNext();) {
					Element node = (Element) ite1.next();
					proVal = node.getText();
					break;
				}
			}
			for (int k = 0; k < proDescriptor.length; k++) {
				if (proDescriptor[k].getName().equalsIgnoreCase(name.getText())) {
					method = proDescriptor[k].getWriteMethod();
					// 利用Java的反射极致调用对象的某个set方法，并将值设置进去
					method.invoke(obj, proVal);
				}
			}
		}
	}

	/**
	 * 获取组件实例
	 */
	@Override
	@SuppressWarnings("unchecked")
	public <T> T create(Class<T> type) {
		Object obj = beanMap.get(type.getSimpleName());
		return (T) obj;
	}

	/**
	 * 根据ID获取组件实例
	 */

	@Override
	@SuppressWarnings("unchecked")
	public <T> T create(Class<T> type, String key) {
		Object obj = beanMap.get(key);
		return (T) obj;
	}
}
